// void, Obj This, Obj target

Hero this;
Obj o;
int x;
bool bSquadTarget;
bool bAnimalTarget;
point dpt, pt;

Sleep(30);
this = This.AsHero;
if(!.IsValid) return;
if (!target.IsValid)
	return;

pt = target.posRH;

if(.InHolder || .PathTo(target, .FormRadius, 0) > .sight){

	.FormSetupAndMoveTo(target, 0, 0, true);

	while(1){
	
		if(!.HasPath) break;
		
		if(.DistTo(pt) <= .sight) break;
		
		.FormKeepMoving(1500);
	}
} else {
	if(.HasArmy){
		bSquadTarget = true;
		if(target.IsAlive())
			if(target.AsUnit.hero.IsValid)
				if(target.AsUnit.hero.command == "retreat_notai" ||
					target.AsUnit.hero.command == "retreat_bld_notai")
					bSquadTarget = false;
		
		if(bSquadTarget){
			Sleep(rand(200)+100);
			.AddCommand(true, "advance", pt);
			.AddCommand(true, "engage");
			return;
		}
	}
}

while(!.IsArmyOutside) 
		.FormKeepMoving(500);	
	
if(.HasArmy){
		
	while(.HasPath()){

		if(.IsEnemyInSquadSight()){	  	
			bSquadTarget = false;
			
			o = .BestTargetInSquadSight();
			
			if(o.IsAlive()) if(o.attack>0) if(o.IsMilitary || o.IsHeirOf("Catapult"))
				bSquadTarget = true;
				
			for(x=0; !bSquadTarget && x<.army.count; x+=1){
			
				if(.army[x].AsUnit.IsValid){
					o = .army[x].AsUnit.BestTargetInSquadSight();
					
					if(o.IsAlive()){
						if(target.IsMilitary){
							if(o.attack>0) if(o.IsMilitary || o.IsHeirOf("Catapult"))
								bSquadTarget = true;
						} else if(target.IsHeirOf("BaseAnimal")
							   || target.IsHeirOf("Peasant")){
							bAnimalTarget = true;
						}
					}
				}
			}
			if(o.IsAlive())
				if(o.AsUnit.hero.IsValid)
					if(o.AsUnit.hero.command == "retreat_notai" ||
						o.AsUnit.hero.command == "retreat_bld_notai")
						bSquadTarget = false;
			
			if(bSquadTarget){
				Sleep(rand(200)+100);
				.AddCommand(true, "advance", pt);
				.AddCommand(true, "engage");
				return;
			} else if(bAnimalTarget){
				Sleep(rand(200)+100);
				.AddCommand(true, "advance", pt);
				.AddCommand(true, "engage");
				return;
			}
		}

		.FormKeepMoving (1500);
	}	

	dpt = .GetFinalPartyOrientation() - Point(1024, 1024);

	if(dpt.x!=0 || dpt.y!=0)
		.Face(.pos+dpt);

} else { // bohater bez armii

	if(!target.IsValid)
		return;

	if(!.IsValidTarget(target))
		return;
			
	// hero attack
	while(target.IsAlive() && .IsValidTarget(target)){

		Sleep(rand(100) + 30); // Disperse the times
		
		while(!.GotoAttack(target, 1500, true, 15000)){
		
			if(!target.IsAlive() || !.IsValidTarget(target)) break;
		}

		if(target.IsAlive() && .IsValidTarget(target)){
		
			while(.Attack(target));
		}
	}
	Sleep(rand(200)+100);
	.AddCommand(true, "engage_unit_type", target);
}